#include "main.h"


void setup() 
{
  int count = 0;
  Serial.begin(9600);               //调试串口初始化
  Su03t.begin();                    //语音模块串口初始化
  button.attach(BUTTONPIN, INPUT);  //按键按下高电平 
  button.interval(5);               //5ms周期消抖
   InitLED_Matrix();                 //初始化LED矩阵显示
  ShowMessage(matrix, "SZJLC!", 6, matrix->Color(255, 0, 255));
  delay(1000);
  
  //初始化DHT11温湿度传感器
  dht.begin();
  //初始化DS1302
  rtc.init();
  // 初始化振动电机引脚为输出模式
  pinMode(motorPin, OUTPUT);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);  //尝试连接WIFI网络
  delay(500);
  //尝试连接直至超时
  while (WiFi.status() != WL_CONNECTED) 
  {
    count++;
    if (count > WIFI_RETRY_COUNT)
      break;
    WifiSearchAnim(matrix, 24, 0);
  }

  //如果WIFI正确连接，则从NTP服务器尝试自动对时
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("wifi connection successful.\r\n");
    //显示WIFI连接成功画面
    WifiCheckAnim(matrix, 27, 1);

    bool state = false;
    char getTimeCount = 0;
    while( state == false )
    {
      getNtpTimeAnim(matrix, 24, 0);//显示正在获取网络时间画面
      state = getTimeNTP();//更新获取时间的状态
      //如果获取超时
      if( (getTimeCount++) > GET_TIME_TIMEOUT ) 
        break;
    }
    if( getTimeCount >= GET_TIME_TIMEOUT )
    {
      getTimeCount = 0;
      NtpTimeFailAnim(matrix, 27, 1);//显示获取网络时间失败画面
      Serial.println("Fetch time timeout.\r\n");
    }
    else
    {
      getTimeCount = 0;
      NtpTimeCheckAnim(matrix, 27, 1);//显示获取网络时间成功画面
      Serial.println("Time setting is successful.\r\n");
    }
    weather.update();
    weatherid = weather.getWeather(1,1);
    
    ShowMessage(matrix, "ONLINE", 6, matrix->Color(0, 255, 0));
    vibrationMotor.vibrate(500); // 控制振动电机振动500ms
    delay(1000);
  }
  else
  {
    ShowMessage(matrix, "OFFLINE", 7, matrix->Color(255, 0, 0));
    vibrationMotor.vibrate(1000); // 控制振动电机振动1秒
    delay(1000);
  }
  WiFi.disconnect();
  delay(500);
}


void loop() 
{
  char disp_buf[40];

  button.update();    //更新按键状态

  if (need_set_time) //如果需要对时
  {
    need_set_time = false; //反转对时状态，并从ntp取回来时间并更新DS1302的时间
    InitDS1302();
  }

  if(minute % 20 == 19)
    getweather = 1;

  if(minute % 20 == 0 && getweather)  //getweather标志位是为了在每次到达20min时只更新一次天气数据，否则会导致内存溢出而重启
  {
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    delay(500);
    if(WiFi.status() == WL_CONNECTED)
    {
      weather.update();
      weatherid = weather.getWeather(is_today, is_day);
    }
    WiFi.disconnect();
    getweather = 0;
  }

  //如果当前显示的不是拾音器
  if( display != music_fft )
  {
    readRtc(); //将时间从DS1302中取出并显示
  }
  
  switch (display)//切换展示内容
  {
    case timedisplay://显示时间
      matrix->clear();//清屏
      matrix->setTextColor(matrix->Color(0, 0, 255));//设置文本颜色
      matrix->setCursor(3, 5);//设置显示起始坐标
      sprintf(disp_buf, "%02d:%02d:%02d\0", hour, minute, second);//格式化时间字符串
      matrix->print(disp_buf);//显示时分秒
      weekBarDisplay(matrix,week);//显示周（特殊的显示方式）
      matrix->show();//更新显示
      break;

    case weatherdisplay://今明日天气
      if(hour < 6 || hour >= 18)
        is_day = 0;
      else
        is_day = 1;
      matrix->clear();
      //显示最低与最高温度
      matrix->setTextColor(matrix->Color(255,140,0));
      matrix->setCursor(9,5);
      sprintf(disp_buf, "%02d", weather.getTempMin(is_today));
      matrix->print(disp_buf);
      matrix->setCursor(22,5);
      sprintf(disp_buf, "%02d", weather.getTempMax(is_today));
      matrix->print(disp_buf);

      //显示部分图标与文字
      matrix->drawPixel(17,3,matrix->Color(255,140,0));
      matrix->drawPixel(18,2,matrix->Color(255,140,0));
      matrix->drawPixel(19,3,matrix->Color(255,140,0));
      matrix->drawPixel(20,2,matrix->Color(255,140,0));

      matrix->drawPixel(30,3,matrix->Color(255,140,0));
      matrix->drawPixel(30,4,matrix->Color(255,140,0));
      matrix->drawPixel(30,5,matrix->Color(255,140,0));
      matrix->drawPixel(31,3,matrix->Color(255,140,0));
      matrix->drawPixel(31,5,matrix->Color(255,140,0));
      matrix->drawPixel(31,1,matrix->Color(255,140,0));
      
      //显示今明日标识
      dayBarDisplay(matrix,is_today);
      WeatherIcon(matrix, 0, 0, weather.getWeather(is_today, is_day));
      
      //在切换今明日天气显示时实现渐变效果
      if(second%20 == 0)
        change = 1;
      
      if(change)
      {
        switch(dir)
        {
          case 0:
            brightness -= BRIGHTNESS_INTERVAL;
            matrix->setBrightness(brightness);
            break;
          case 1:
            brightness += BRIGHTNESS_INTERVAL;
            matrix->setBrightness(brightness);
            break;
        }
        if(brightness == 0)
        {
          dir = 1;
          is_today = 1 - is_today;
        }
        else if(brightness == BRIGHTNESS)
        {
          dir = 0;
          change = 0;
          delay(1000);  //保证代码执行完不在每20s的条件内
        }
      }  
      matrix->show();
      break;

    case roomparameter://室内温湿度,由DHT11读取
      readDHT(); //将温湿度参数取出并显示

      matrix->clear();

      //显示温湿度图标
      TempIcon(matrix,1,0);
      HumidIcon(matrix,17,0);

      //显示DHT11记录的温湿度
      matrix->setCursor(9,5);
      sprintf(disp_buf, "%02.0d", (int)temperature);
      matrix->print(disp_buf);
      matrix->setCursor(23,5);
      sprintf(disp_buf, "%02.0d", (int)humidity);
      matrix->print(disp_buf);
      matrix->show();
      break;

    case raindisplay://数字雨动画
      ++rain_count;
      if(rain_count >= 5)
      {
        matrix->clear();
        showRainingCode(matrix);
        matrix->show();
        rain_count = 0;
      }
      break;

    case music_fft://音乐频谱,由MAX4466接收声音并进行FFT显示
      matrix->clear();
      showFFT();
      matrix->show();
      break;
  }
  
  //按键按下
  if( button.read() == LOW )
  {
    if( button.currentDuration() >= 2000 )//按超过2000ms
    {
        while( 0 == network.networkTask() )//WIFI配网
        {
          delay(30);
        }
        Serial.println("networkTask end"); 
    }
  }

  if(button.rose())//根据按键是否释放确定状态转换
  {
    vibrationMotor.vibrate(100); // 控制振动电机振动100ms
    displaySwitch(display);      // 显示切换
  }

  //亮度自动控制
  if( change == 0 )//如果当前没有进入显示天气模式的今明日切换状态
    lightAutoControl(matrix);
  delay(50);
}

